using System;
using Engine;
using GameEntitySystem;
using TemplatesDatabase;

using System.Collections.Generic;

using Game;
namespace IndustrialAge
{
	public class ComponentBeamE : ComponentMachine, IUpdateable
	{
		public int ln;

		public override int RemainsSlotIndex => SlotsCount - 1;

		public override int ResultSlotIndex => SlotsCount - 1;

		public override int FuelSlotIndex => SlotsCount - 1;

		public bool nr;

		public bool nr2;

		public bool nr3;

		public Dictionary<Point3, NParticleSystem3> m_particleSystemsByCell = new Dictionary<Point3, NParticleSystem3>();

		public override int GetSlotCapacity(int slotIndex, int value)
		{
			
			int v = GetSlotValue(slotIndex);
			if ((v == 262384 || v == 786672 || v == 1048816 || v == 1310960 || v == WaterBlock.Index || v == MagmaBlock.Index) && value != v && v != 0)
			{
				return 0;
			}
			if (slotIndex >= 0 && slotIndex < m_slots.Count)
			{
				return BlocksManager.Blocks[Terrain.ExtractContents(value)].MaxStacking;
			}
			return 0;
		}

		public override void ProcessSlotItems(int slotIndex, int value, int count, int processCount, out int processedValue, out int processedCount)
		{
			int slotCount = GetSlotCount(slotIndex);
			int slotValue = GetSlotValue(slotIndex);
			if (slotCount > 0 && slotValue != 0)
			{
				SubsystemBlockBehavior[] blockBehaviors = base.Project.FindSubsystem<SubsystemBlockBehaviors>(throwOnError: true).GetBlockBehaviors(Terrain.ExtractContents(slotValue));
				foreach (SubsystemBlockBehavior subsystemBlockBehavior in blockBehaviors)
				{
					int processInventoryItemCapacity = subsystemBlockBehavior.GetProcessInventoryItemCapacity(this, slotIndex, value);
					if (processInventoryItemCapacity > 0)
					{
						subsystemBlockBehavior.ProcessInventoryItem(this, slotIndex, value, count, MathUtils.Min(processInventoryItemCapacity, processCount), out processedValue, out processedCount);
						return;
					}
				}
			}
			processedValue = value;
			processedCount = count;
		}

		public new void DropAllItems(Vector3 position)
		{
			Point3 coordinates = m_componentBlockEntity.Coordinates;
			Point3 key = new Point3(coordinates.X, coordinates.Y, coordinates.Z);
			NParticleSystem3 particleSystem = m_particleSystemsByCell[key];
			Utils.SubsystemParticles.RemoveParticleSystem(particleSystem);
			m_particleSystemsByCell.Remove(key);

			
			for (int iii = 0; iii < Utils.SubsystemSour.m_radations.Count; iii++)
			{
				if (Utils.SubsystemSour.m_radations.Array[iii] == new Vector4(coordinates.X, coordinates.Y, coordinates.Z, 40f))
				{
					//	flag = true; break;
					Utils.SubsystemSour.m_radations.Remove(new Vector4(coordinates.X, coordinates.Y, coordinates.Z, 40f));
				}
			}
			base.DropAllItems(position);
		}

		public void Update(float dt)
		{
			Point3 coordinates = m_componentBlockEntity.Coordinates;
			if (nr3)
			{
				NParticleSystem3 fireParticleSystem = new NParticleSystem3(new Vector3(coordinates.X, coordinates.Y, coordinates.Z) + new Vector3(.5f), 1f, 40f);
				Utils.SubsystemParticles.AddParticleSystem(fireParticleSystem);
				m_particleSystemsByCell[new Point3(coordinates.X, coordinates.Y, coordinates.Z)] = fireParticleSystem;
				nr3 = false;
			}
			if (ln>=4 && GetSlotCount(0)>0 && GetSlotValue(0)== ItemBlock.IdTable["D靶丸"])
			{
				//Utils.SubsystemParticles.AddParticleSystem(new NParticleSystem3(new Vector3(x, y, z), 1f, 40f));
				nr = true;
			}else
			{
				//HeatLevel = 0f;
				//nr = false;
			}
			
			TerrainChunk chunk = Utils.Terrain.GetChunkAtCell(coordinates.X, coordinates.Z);
			if (chunk != null && chunk.State == TerrainChunkState.Valid && nr)
			{
				//Utils.SubsystemParticles.AddParticleSystem(new NParticleSystem3(new Vector3(coordinates.X, coordinates.Y, coordinates.Z)+ new Vector3(.5f), 1f, 40f));
				nr = false;
				nr2 = true;
				m_fireTimeRemaining = 100f;
				HeatLevel = 6400f;
				m_slots[0].Count -= 1;
				SmeltingProgress = MathUtils.Min(m_fireTimeRemaining / 100f, 5f);
				NParticleSystem3 fireParticleSystem = new NParticleSystem3(new Vector3(coordinates.X, coordinates.Y, coordinates.Z) + new Vector3(.5f), 1f, 40f);
				Utils.SubsystemParticles.AddParticleSystem(fireParticleSystem);
				m_particleSystemsByCell[new Point3(coordinates.X, coordinates.Y, coordinates.Z)] = fireParticleSystem;


				bool flag = false;
				
					for (int iii = 0; iii < Utils.SubsystemSour.m_radations.Count; iii++)
					{
						if (Utils.SubsystemSour.m_radations.Array[iii] == new Vector4(coordinates.X, coordinates.Y, coordinates.Z, 40f))
						{
							flag = true; break;
						}
					}
				if (Utils.SubsystemSour.m_radations.Count == 0 || !flag)
					Utils.SubsystemSour.m_radations.Add(new Vector4(coordinates.X, coordinates.Y, coordinates.Z, 40f));

				//int cellValue = chunk.GetCellValueFast(coordinates.X & 15, coordinates.Y, coordinates.Z & 15);
				//Utils.SubsystemTerrain.ChangeCell(coordinates.X, coordinates.Y, coordinates.Z, Terrain.ReplaceData(cellValue, FurnaceNBlock.SetHeatLevel(Terrain.ExtractData(cellValue), (int)MathUtils.Sign(HeatLevel))));
			}
			if (HeatLevel > 0f)
			{
				m_fireTimeRemaining = MathUtils.Max(0f, m_fireTimeRemaining - dt * 1f);
				SmeltingProgress = MathUtils.Min(m_fireTimeRemaining / 100f, 1f);
				if (m_fireTimeRemaining <= 0f)
				{
					HeatLevel = 0f;
					
					Point3 key = new Point3(coordinates.X, coordinates.Y, coordinates.Z);
					NParticleSystem3 particleSystem = m_particleSystemsByCell[key];
					Utils.SubsystemParticles.RemoveParticleSystem(particleSystem);
					m_particleSystemsByCell.Remove(key);


					bool flag = false;

					for (int iii = 0; iii < Utils.SubsystemSour.m_radations.Count; iii++)
					{
						if (Utils.SubsystemSour.m_radations.Array[iii] == new Vector4(coordinates.X, coordinates.Y, coordinates.Z, 40f))
						{
							//	flag = true; break;
							Utils.SubsystemSour.m_radations.Remove(new Vector4(coordinates.X, coordinates.Y, coordinates.Z, 40f));
						}
					}
					//if (Utils.SubsystemSour.m_radations.Count == 0 || !flag)
					//	Utils.SubsystemSour.m_radations.Add(new Vector4(coordinates.X, coordinates.Y, coordinates.Z, 20f));

				}
			}
			ln = 0;
			
		}
		public override void Load(ValuesDictionary valuesDictionary, IdToEntityMap idToEntityMap)
		{
			base.Load(valuesDictionary, idToEntityMap);
			//Point3 coordinates = m_componentBlockEntity.Coordinates;
			if (HeatLevel>0f)
			{
				nr3 = true;
			//	NParticleSystem3 fireParticleSystem = new NParticleSystem3(new Vector3(coordinates.X, coordinates.Y, coordinates.Z) + new Vector3(.5f), 1f, 40f);
			//	Utils.SubsystemParticles.AddParticleSystem(fireParticleSystem);
			//	m_particleSystemsByCell[new Point3(coordinates.X, coordinates.Y, coordinates.Z)] = fireParticleSystem;
			}
			//m_speed = valuesDictionary.GetValue("Speed", 1f);
		}
	}
	public class ComponentFireBox : ComponentMachine, IUpdateable
	{
		protected string m_smeltingRecipe;

		//protected int m_music;

		protected float m_fireTime;

		protected float m_speed;

		public override int RemainsSlotIndex => SlotsCount - 1;

		public override int ResultSlotIndex => SlotsCount - 1;

		public override int FuelSlotIndex => SlotsCount - 1;

		public void Update(float dt)
		{
			Point3 coordinates = m_componentBlockEntity.Coordinates;
			if (coordinates.Y < 0 || coordinates.Y > 127)
				return;
			if (HeatLevel > 0f)
			{
				m_fireTimeRemaining = MathUtils.Max(0f, m_fireTimeRemaining - dt * m_speed);
				if (m_fireTimeRemaining == 0f)
					HeatLevel = 0f;
			}
			Slot slot;
			if (m_updateSmeltingRecipe)
			{
				m_updateSmeltingRecipe = false;
				if (HeatLevel <= 0f)
				{
					slot = m_slots[FuelSlotIndex];
					if (slot.Count > 0)
					{
						var block = BlocksManager.Blocks[Terrain.ExtractContents(slot.Value)];
						HeatLevel = block is IFuel fuel ? fuel.GetHeatLevel(slot.Value) : block.FuelHeatLevel;
					}
				}
				if (!"CoalPowder".Equals(m_smeltingRecipe))
				{
					m_smeltingRecipe = "CoalPowder";
					SmeltingProgress = 0f;
					//m_music = 0;
				}
			}
			if (m_smeltingRecipe == null)
			{
				HeatLevel = 0f;
				m_fireTimeRemaining = 0f;
				//m_music = -1;
			}
			else if (m_fireTimeRemaining <= 0f)
			{
				slot = m_slots[FuelSlotIndex];
				if (slot.Count > 0)
				{
					var block = BlocksManager.Blocks[Terrain.ExtractContents(slot.Value)];
					if (block.GetExplosionPressure(slot.Value) > 0f)
					{
						slot.Count = 0;
						Utils.SubsystemExplosions.TryExplodeBlock(coordinates.X, coordinates.Y, coordinates.Z, slot.Value);
					}
					else
					{
						slot.Count--;
						if (block is IFuel fuel)
						{
							HeatLevel = fuel.GetHeatLevel(slot.Value);
							m_fireTime = m_fireTimeRemaining = fuel.GetFuelFireDuration(slot.Value);
						}
						else
						{
							HeatLevel = block.FuelHeatLevel;
							m_fireTime = m_fireTimeRemaining = block.FuelFireDuration;
						}
					}
				}
			}
			if (m_fireTimeRemaining <= 0f)
			{
				m_smeltingRecipe = null;
				SmeltingProgress = 0f;
				//m_music = -1;
			}
			if (m_smeltingRecipe != null)
			{
				if (m_fireTime == 0f)
					m_fireTime = m_fireTimeRemaining;
				SmeltingProgress = MathUtils.Min(m_fireTimeRemaining / m_fireTime, 1f);
				if (SmeltingProgress >= 2f)
				{
					m_smeltingRecipe = null;
					SmeltingProgress = 0f;
					m_updateSmeltingRecipe = true;
				}
			}
			TerrainChunk chunk = Utils.Terrain.GetChunkAtCell(coordinates.X, coordinates.Z);
			if (chunk != null && chunk.State == TerrainChunkState.Valid)
			{
				int cellValue = chunk.GetCellValueFast(coordinates.X & 15, coordinates.Y, coordinates.Z & 15);
				Utils.SubsystemTerrain.ChangeCell(coordinates.X, coordinates.Y, coordinates.Z, Terrain.ReplaceData(cellValue, FurnaceNBlock.SetHeatLevel(Terrain.ExtractData(cellValue), (int)MathF.Sign(HeatLevel))));
			}
		}

		public override void Load(ValuesDictionary valuesDictionary, IdToEntityMap idToEntityMap)
		{
			base.Load(valuesDictionary, idToEntityMap);
			m_speed = valuesDictionary.GetValue("Speed", 1f);
		}
	}
}